package com.example.shiro;


import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 安全管理器
 */

@Configuration
public class ShiroConfig  {

    @Bean
    public CredentialsMatcher getCredentialsMatcher(){

        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();

        hashedCredentialsMatcher.setHashAlgorithmName("md5");

        hashedCredentialsMatcher.setHashIterations(2);

        return hashedCredentialsMatcher;
    }

    @Bean
    public Realm getRealm(){
        MyShiroRealm realm = new MyShiroRealm();


        realm.setAuthenticationCachingEnabled(true);

        realm.setAuthorizationCacheName("authorizationCacheName");

        realm.setCredentialsMatcher(getCredentialsMatcher());

        return realm;
    }

    public RedisManager redisManager(){
        RedisManager redisManager = new RedisManager();

        return redisManager;
    }

    public RedisCacheManager redisCacheManager(){
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        redisCacheManager.setPrincipalIdFieldName("usrId");

        return redisCacheManager;
    }

    public RedisSessionDAO redisSessionDAO(){
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());

        return redisSessionDAO;
    }

    public DefaultWebSessionManager defaultWebSessionManager(){

        DefaultWebSessionManager defaultWebSecurityManager = new DefaultWebSessionManager();
        defaultWebSecurityManager.setSessionDAO(redisSessionDAO());
        return defaultWebSecurityManager;
    }


    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
//        myShiroRealm.setCachingEnabled(true);
        myShiroRealm.setAuthorizationCachingEnabled(true);
        myShiroRealm.setAuthorizationCacheName("authorizationCache");
        myShiroRealm.setAuthenticationCachingEnabled(true);
        myShiroRealm.setAuthenticationCacheName("authenticationCache");
        return myShiroRealm;
    }

    @Bean
    public SecurityManager securityManager(){

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        securityManager.setRealm(myShiroRealm());

        securityManager.setCacheManager(redisCacheManager());

        securityManager.setSessionManager(defaultWebSessionManager());

        return securityManager;

    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){

        ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
        shiroFilterFactory.setSecurityManager(securityManager);
//        shiroFilterFactory.setLoginUrl("/index");
//        shiroFilterFactory.setSuccessUrl("main");

        Map<String ,String> fileterChainDefinitionMap = new LinkedHashMap<>();

        fileterChainDefinitionMap.put("/css/*","anon");
        fileterChainDefinitionMap.put("/fonts/*","anon");
        fileterChainDefinitionMap.put("/images/*","anon");
        fileterChainDefinitionMap.put("/js/*","anon");
        fileterChainDefinitionMap.put("/localcss/*","anon");
        fileterChainDefinitionMap.put("/localjs/*","anon");

        fileterChainDefinitionMap.put("/dologin","anon");
        fileterChainDefinitionMap.put("logout","anon");
        fileterChainDefinitionMap.put("/login","anon");
        fileterChainDefinitionMap.put("/user/list","perms[L0601]");


//        fileterChainDefinitionMap.put("/*","authc");

        shiroFilterFactory.setUnauthorizedUrl("/403");
        shiroFilterFactory.setFilterChainDefinitionMap(fileterChainDefinitionMap);

        shiroFilterFactory.setLoginUrl("/login");

        return shiroFilterFactory;
    }

}
